package com.chinairi.mall.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chinairi.common.utils.IdGenerator;
import com.chinairi.common.utils.UserSession;
import com.chinairi.mall.controller.viewobject.ProjectPlanReturnVO;
import com.chinairi.mall.dao.ProjectPlanReturnDetailMapper;
import com.chinairi.mall.dao.ProjectPlanReturnMapper;
import com.chinairi.mall.model.ProjectPlanReqDetail;
import com.chinairi.mall.model.ProjectPlanReturn;
import com.chinairi.mall.model.ProjectPlanReturnDetail;
import com.chinairi.mall.service.IProjectPlanReturnService;
import com.chinairi.mall.service.modelobject.ProjectPlanReturnMO;
import com.chinairi.mall.util.VerificationCodeUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author gsl
 * @since 2020-10-24
 */
@Service
public class ProjectPlanReturnServiceImpl extends ServiceImpl<ProjectPlanReturnMapper, ProjectPlanReturn> implements IProjectPlanReturnService {

    @Autowired
    private ProjectPlanReturnMapper projectPlanReturnMapper;

    @Autowired
    private ProjectPlanReturnDetailMapper projectPlanReturnDetailMapper;

    /**
     * 新增退料
     *
     * @param projectPlanReturnVO
     */
    @Override
    public void addReturn(ProjectPlanReturnVO projectPlanReturnVO) {
        String pprId = VerificationCodeUtil.DateCreate(new Date());
        projectPlanReturnVO.setPprId(pprId);
        projectPlanReturnVO.setCreateTime(new Date());
        projectPlanReturnVO.setCreateUser(UserSession.getUserId());
        projectPlanReturnVO.setPprState("0");
        projectPlanReturnMapper.insert(projectPlanReturnVO);
        for (ProjectPlanReturnDetail projectPlanReturnDetail : projectPlanReturnVO.getProjectPlanReturnDetailList()) {
            projectPlanReturnDetail.setPprId(pprId);
            projectPlanReturnDetail.setPprdId(IdGenerator.UUID());
            projectPlanReturnDetail.setCreateTime(new Date());
            projectPlanReturnDetail.setCreateUser(UserSession.getUserId());
        }
        projectPlanReturnMapper.batchInsertReturnDetail(projectPlanReturnVO.getProjectPlanReturnDetailList());
    }

    /**
     * 获取退料列表
     *
     * @return
     */
    @Override
    public List<ProjectPlanReturn> getList(String flag) {
        QueryWrapper<ProjectPlanReturn> returnQueryWrapper = new QueryWrapper<>();
        if ("0".equals(flag)) {
            returnQueryWrapper.eq("CREATE_USER", UserSession.getUserId())
                    .orderByDesc("CREATE_TIME");
        }
        return projectPlanReturnMapper.selectList(returnQueryWrapper);
    }


    /**
     * 获取退料单详情
     *
     * @param pprId
     * @return
     */
    @Override
    public ProjectPlanReturnVO getReturnDetail(String pprId) {
        ProjectPlanReturnVO projectPlanReturnVO = new ProjectPlanReturnVO();
        ProjectPlanReturn projectPlanReturn = projectPlanReturnMapper.selectById(pprId);
        BeanUtils.copyProperties(projectPlanReturn, projectPlanReturnVO);
        List<ProjectPlanReturnDetail> list = projectPlanReturnMapper.getListByPPRId(pprId);
        projectPlanReturnVO.setProjectPlanReturnDetailList(list);
        return projectPlanReturnVO;
    }

    /**
     * 更新退料单状态
     *
     * @param pprId
     * @param state
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateState(String pprId, String state) {
        ProjectPlanReturn projectPlanReturn = new ProjectPlanReturn();
        projectPlanReturn.setPprId(pprId);
        projectPlanReturn.setPprState(state);
        projectPlanReturnMapper.updateById(projectPlanReturn);
        /**
         * 思路：查出来此退料单的所有物料ID和数量List，以及此退料单的需求计划ID
         * 然后用需求计划ID和物料ID查出对应的需求计划详情列表
         * 更新需求计划的领料数量（减）
         * 用map放
         */
        if ("2".equals(state)) {
            List<ProjectPlanReturnMO> projectPlanReturnMOList = projectPlanReturnMapper.selectMatNum(pprId);
            List<String> returnMatDbId = new ArrayList<>();
            String planReqId = "";
            Map<String, Float> returnMatNum = new HashMap<>(projectPlanReturnMOList.size());
            for (ProjectPlanReturnMO projectPlanReturnMO : projectPlanReturnMOList) {
                planReqId = projectPlanReturnMO.getPlanReqId();
                returnMatDbId.add(projectPlanReturnMO.getPprdMatCode());
                returnMatNum.put(projectPlanReturnMO.getPprdMatCode(), projectPlanReturnMO.getPprdNumber());
            }
            List<ProjectPlanReqDetail> projectPlanReqDetailList = projectPlanReturnMapper.selectReqMatNum(planReqId, returnMatDbId);
            projectPlanReturnMapper.batchUpdatePlanReqDetailNum(projectPlanReqDetailList.stream().peek((list) -> {
                list.setPlanCollectedNum(list.getPlanCollectedNum() - returnMatNum.get(list.getPlanMatCode()));
            }).collect(Collectors.toList()));
        }
    }

    /**
     * 过滤可退料的
     *
     * @param projectPlanReturnVO
     * @return
     */
    @Override
    public ProjectPlanReturnVO filterReturnMat(ProjectPlanReturnVO projectPlanReturnVO) {
        /**
         * 思路：
         * 1、前端传入需求计划ID和物料List
         * 2、根据需求计划ID查询所有未被处理的退料单（state = 1 的）
         * 3、然后查出这些退料单List<String>中的详细物料详情，批量查询出所有的物料ID List<string>
         * 4、在一个退料单详情中遍历所有的物料id，并和传来的物料编码作对比
         * 5、如果查出来的List<ReturnDerail>中已经存在此物料，则从传来的List<projectPlanReturnDetail>中remove此物料
         * 6、最后返回projectPlanReturnVO
         */
        //根据需求计划ID查询所有未被处理的退料单
        List<String> pprIdList = projectPlanReturnMapper.selectReturn(projectPlanReturnVO.getPlanReqId());
        List<ProjectPlanReturnDetail> projectPlanReturnDetailList = projectPlanReturnVO.getProjectPlanReturnDetailList();
        List<ProjectPlanReturnDetail> planReturnDetailList = new ArrayList<>();
        if (pprIdList.size() > 0) {
            List<String> matCodeList = projectPlanReturnMapper.selectBatchByPprId(pprIdList);
            Set matCodeSet = new HashSet(matCodeList);
            for (ProjectPlanReturnDetail planReturnDetail : projectPlanReturnDetailList) {
                if (matCodeSet.contains(planReturnDetail.getPprdMatCode()) || planReturnDetail.getPprdSignedNumber() <= 0) {
                    planReturnDetailList.add(planReturnDetail);
                }
            }
        } else {
            for (ProjectPlanReturnDetail planReturnDetail : projectPlanReturnDetailList) {
                if (planReturnDetail.getPprdSignedNumber() <= 0) {
                    planReturnDetailList.add(planReturnDetail);
                }
            }
            projectPlanReturnDetailList.removeAll(planReturnDetailList);
        }
        projectPlanReturnDetailList.removeAll(planReturnDetailList);
        return projectPlanReturnVO;
    }
}
